<template>
  <el-dialog
    :visible.sync="dialogVisible"
    append-to-body
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    :show-close="false"
    :before-close="beforeClose"
    class="tag-edit-dialog tag-deep-dialog"
    width="70%"
    v-dialogMove
  >
    <span class="el-dialog__title" slot="title">画像深入分析 <span class="title-tips">点击图像选择维度</span></span>
    <div id="deep-box"></div>
    <div class="show-box">
      <div class="box-title">已选区间列表</div>
      <div class="show-content tag-scrollbar">
        <ul v-if="drillGrps.length">
          <li v-for="(item, index) in drillGrps" :key="index">
            {{ item.mainDrill.tagNm }}（{{ item.mainDrill.name }}）
            <template v-if="item.subDrill && item.subDrill.labId">
              & {{ item.subDrill.tagNm }}（{{ item.subDrill.name }}）
            </template>
          </li>
        </ul>
        <div class="no-record" v-else>暂无内容</div>
      </div>
    </div>
    <span slot="footer" class="dialog-footer">
      <el-button @click="beforeClose">取消</el-button>
      <el-button type="primary" @click="submit">开始分析</el-button>
    </span>
  </el-dialog>
</template>

<script>
import * as echarts from 'echarts'
export default {
  data() {
    return {
      dialogVisible: false,
      profile: {},
      grpFlter: {},
      grpTotal: 0,
      chart: null,
      colorList: ['#0f80ff', '#11ce98', '#f79e2a', '#7886c5', '#e8d318', '#4dad30', '#f3b177'],
      drillGrps: []
    }
  },
  computed: {
    axisTips() {
      const tips1 =
        this.grpFlter.mainGrp.tagNm +
        ' X ' +
        (this.grpFlter.subGrp && this.grpFlter.subGrp.labId ? this.grpFlter.subGrp.tagNm : '数值')
      const tips2 =
        (this.grpFlter.subGrp && this.grpFlter.subGrp.labId ? this.grpFlter.subGrp.tagNm : '数值') +
        ' X ' +
        this.grpFlter.mainGrp.tagNm
      return this.grpFlter.mainGrp.graphType === 'bar' ? tips1 : tips2
    }
  },
  methods: {
    showDialog(profile, grpFlter, grpTotal) {
      this.profile = profile
      this.grpFlter = grpFlter
      this.grpTotal = grpTotal
      this.dialogVisible = true
      this.$nextTick(() => {
        if (profile.graphType === 'bar' || profile.graphType === 'stack') this.initBarChart()
        else if (profile.graphType === 'pie' || profile.graphType === 'circle') this.initPieChart()
        else if (profile.graphType === 'heat') this.initHeatChart()
      })
    },
    initBarChart() {
      this.chart = echarts.init(document.getElementById('deep-box'))
      const _this = this
      let xAxis = []
      let yAxis = []
      let rotate = 0
      let series = []
      let subText = []
      let seriesParam = {}
      let isDimen = false
      if (this.profile.subLabId) {
        // 堆叠图
        isDimen = true
        this.profile.labGrps.forEach(item => {
          let label = item.desc || item.code
          let subLabel = item.subDesc
          if (
            this.grpFlter.mainGrp.valueType == '6' ||
            this.grpFlter.mainGrp.valueType == '7' ||
            this.grpFlter.subGrp.valueType == '6' ||
            this.grpFlter.subGrp.valueType == '7'
          ) {
            label = label.replace(/-/g, ' -∞').replace(/[+]/g, ' +∞')
            subLabel = subLabel.replace(/-/g, ' -∞').replace(/[+]/g, ' +∞')
          }
          if (!xAxis.includes(label)) xAxis.push(label)
          if (!seriesParam[subLabel]) {
            seriesParam[subLabel] = {
              [label]: item.value
            }
          } else {
            seriesParam[subLabel][label] = item.value
          }
          if (label && label.length >= 5) rotate = 40
        })
        Object.keys(seriesParam).forEach((item, sindex) => {
          let xData = []
          let color = ''
          if (sindex <= this.colorList.length) color = this.colorList[sindex]
          else {
            let r = Math.floor(Math.random() * 256)
            let g = Math.floor(Math.random() * 256)
            let b = Math.floor(Math.random() * 256)
            color = 'rgb(' + r + ',' + g + ',' + b + ')'
          }
          xAxis.forEach(xLabel => {
            xData.push(seriesParam[item][xLabel] ? seriesParam[item][xLabel] : 0)
          })
          series.push({
            name: item,
            type: 'bar',
            color: color,
            selectedMode: 'multiple',
            barWidth:
              (this.grpFlter.mainGrp.graphType === 'stack' && xAxis.length >= 5) || xAxis.length > 10 ? null : 30,
            stack: 'profile',
            data: xData
          })
        })
      } else {
        if (this.profile.groupTyp === 'enum') {
          this.profile.labGrps.forEach(item => {
            let label = item.desc || item.code
            xAxis.push(label)
            yAxis.push(item.value)
            if (item.desc && item.desc.length >= 5) rotate = 40
          })
        } else {
          Object.values(this.grpFlter.mainGrp.rangeInfo).forEach(item => {
            let label = item
            const target = this.profile.labGrps.find(grp => grp.desc === label)
            if (Number(this.grpFlter.mainGrp.valueType) === 6 || Number(this.grpFlter.mainGrp.valueType) === 7) {
              label = label.replace(/-/g, ' -∞')
              label = label.replace(/[+]/g, ' +∞')
            }
            xAxis.push(label)
            yAxis.push(target ? target.value : 0)
            if (label && label.length >= 8) rotate = 40
          })
          if (this.profile.numLabGrps) {
            this.profile.numLabGrps.forEach(numLab => {
              subText.push(`{a|${numLab.funcName}} ${numLab.funcResult}`)
            })
          }
        }
        series = [
          {
            type: 'bar',
            barWidth:
              (this.grpFlter.mainGrp.graphType === 'stack' && xAxis.length >= 5) || yAxis.length > 10 ? null : 30,
            data: yAxis,
            selectedMode: 'multiple',
            itemStyle: {
              color: '#0f80ff'
            },
            label: {
              normal: {
                show: true,
                position: this.grpFlter.mainGrp.graphType === 'stack' ? 'right' : 'top',
                color: '#666',
                rotate: this.grpFlter.mainGrp.graphType === 'bar' && yAxis.length > 15 ? 90 : 0,
                align:
                  this.grpFlter.mainGrp.graphType === 'stack' ||
                  (this.grpFlter.mainGrp.graphType === 'bar' && yAxis.length > 15)
                    ? 'top'
                    : 'middle',
                verticalAlign: 'middle',
                formatter: function(params) {
                  return ((params.value / _this.grpTotal) * 100).toFixed(2) + '%'
                }
              }
            }
          }
        ]
      }
      let axisParams1 = [
        {
          type: 'category',
          axisLabel: {
            show: true,
            color: '#666',
            rotate: this.grpFlter.mainGrp.graphType === 'stack' ? 0 : rotate,
            interval: 0,
            formatter: function(params) {
              let label = params
              if (params.length >= 20) {
                label = params.split('~')[0] + '~ \n ' + params.split('~')[1]
              }
              return label
            }
          },
          axisLine: {
            show: true,
            lineStyle: {
              color: '#666'
            }
          },
          axisTick: {
            show: false
          },
          data: xAxis
        }
      ]
      let axisParams2 = {
        type: 'value',
        axisLabel: {
          color: '#666'
        },
        axisLine: {
          show: true,
          lineStyle: {
            color: '#666'
          }
        },
        axisTick: {
          show: true,
          inside: true,
          lineStyle: {
            color: '#eee'
          }
        },
        splitLine: {
          show: true,
          lineStyle: {
            color: '#eee'
          }
        }
      }
      let option = {
        title: [
          {
            text: this.grpFlter.mainGrp.groupName,
            textStyle: {
              fontSize: 16,
              fontWeight: 700
            },
            subtext: subText.join(' '),
            subtextStyle: {
              color: '#63708a',
              rich: {
                a: {
                  padding: [5, 10],
                  lineHeight: 10,
                  color: '#63708a',
                  backgroundColor: '#f2f6ff',
                  borderRadius: 2
                }
              }
            }
          },
          {
            text: this.axisTips,
            top: 1,
            left: this.grpFlter.mainGrp.groupName.length * 15 + 20,
            textStyle: {
              fontSize: 13,
              fontWeight: 700,
              color: '#999'
            }
          }
        ],
        tooltip: isDimen
          ? {
              trigger: 'axis',
              axisPointer: 'shadow',
              confine: true
            }
          : {
              trigger: 'axis',
              confine: true,
              formatter: function(params) {
                return (
                  params[0].name +
                  '<br/>数值：' +
                  params[0].value +
                  '<br/>占比：' +
                  ((params[0].value / _this.grpTotal) * 100).toFixed(2) +
                  '%'
                )
              }
            },
        grid: {
          top: '60',
          left: 0,
          right: '50',
          bottom: 0,
          containLabel: true
        },
        xAxis: this.grpFlter.mainGrp.graphType === 'stack' ? axisParams2 : axisParams1,
        yAxis: this.grpFlter.mainGrp.graphType === 'stack' ? axisParams1 : axisParams2,
        series: series
      }
      this.chart.setOption(option, true)
      this.chart.on('click', params => {
        this.initDrill(params)
      })
      window.addEventListener('resize', () => {
        this.chart.resize()
      })
    },
    initPieChart() {
      this.chart = echarts.init(document.getElementById('deep-box'))
      const _this = this
      let pieData = []
      let subText = []
      this.profile.labGrps.forEach(item => {
        if (this.profile.groupTyp !== 'enum' || (this.profile.groupTyp === 'enum' && item.value !== 0)) {
          let label = item.desc || item.code
          if (Number(this.grpFlter.mainGrp.valueType) === 6 || Number(this.grpFlter.mainGrp.valueType) === 7) {
            label = label.replace(/-/g, ' -∞')
            label = label.replace(/[+]/g, ' +∞')
          }
          pieData.push({
            name: label,
            value: item.value
          })
        }
      })
      if (this.profile.numLabGrps) {
        this.profile.numLabGrps.forEach(numLab => {
          subText.push(`{a|${numLab.funcName}} ${numLab.funcResult}`)
        })
      }
      let option = {
        title: {
          text: this.grpFlter.mainGrp.groupName,
          textStyle: {
            fontSize: 16,
            fontWeight: 700
          },
          subtext: subText.join(' '),
          subtextStyle: {
            color: '#63708a',
            rich: {
              a: {
                padding: [5, 10],
                lineHeight: 10,
                color: '#63708a',
                backgroundColor: '#f2f6ff',
                borderRadius: 2
              }
            }
          }
        },
        tooltip: {
          trigger: 'item',
          // formatter: '{b}<br/>数值：{c}<br/>占比：{d}%'
          formatter: function(params) {
            return (
              params.name +
              '<br />' +
              '数值：' +
              params.value +
              '<br />' +
              '占比：' +
              ((params.value / _this.grpTotal.grpTotal) * 100).toFixed(2) +
              '%'
            )
          }
        },
        series: [
          {
            type: 'pie',
            radius: this.grpFlter.mainGrp.graphType === 'pie' ? '65%' : ['45%', '70%'],
            startAngle: 20,
            top: '15%',
            data: pieData,
            selectedMode: 'multiple',
            label: {
              normal: {
                position: pieData.length >= 30 ? 'inner' : 'outter',
                color: '#666'
              }
            },
            labelLine: {
              lineStyle: {
                color: '#666'
              }
            },
            itemStyle: {
              color(params) {
                // let colorList = ['#475fba', '#8bb4ff', '#ffab34', '#ffdc75', '#baaaf5', '#9983ea']
                let colorList = ['#0f80ff', '#11ce98', '#f79e2a', '#7886c5', '#e8d318', '#4dad30', '#f3b177']
                let r = Math.floor(Math.random() * 256)
                let g = Math.floor(Math.random() * 256)
                let b = Math.floor(Math.random() * 256)
                return params.dataIndex > colorList.length - 1
                  ? 'rgb(' + r + ',' + g + ',' + b + ')'
                  : colorList[params.dataIndex]
              }
            }
          }
        ],
        label: {
          formatter: function(params) {
            let label = params.name
            if (params.name.length >= 20) {
              label = params.name.split('~')[0] + '~ \n ' + params.name.split('~')[1]
            }
            return label
          }
        }
      }
      this.chart.setOption(option, true)
      this.chart.on('click', params => {
        this.initDrill(params)
      })
      window.addEventListener('resize', () => {
        this.chart.resize()
      })
    },
    initHeatChart() {
      this.chart = echarts.init(document.getElementById('deep-box'))
      const _this = this
      let xAxis = []
      let yAxis = []
      let series = []
      let values = this.profile.labGrps.map(item => item.value)
      xAxis = Array.from(
        new Set(
          this.profile.labGrps.map(item => {
            return item.desc || item.code
          })
        )
      )
      yAxis = Array.from(
        new Set(
          this.profile.labGrps.map(item => {
            return item.subDesc || item.subCode
          })
        )
      )
      this.profile.labGrps.forEach(item => {
        let xIndex = xAxis.findIndex(axis => axis === item.desc || axis === item.code)
        let yIndex = yAxis.findIndex(axis => axis === item.subDesc || axis === item.subCode)
        series.push([xIndex, yIndex, item.value])
      })
      xAxis.map(item => {
        return this.grpFlter.mainGrp.valueType == '6' || this.grpFlter.mainGrp.valueType == '7'
          ? item.replace(/-/g, ' -∞').replace(/[+]/g, ' +∞')
          : item
      })
      yAxis.map(item => {
        return this.grpFlter.subGrp.valueType == '6' || this.grpFlter.subGrp.valueType == '7'
          ? item.replace(/-/g, ' -∞').replace(/[+]/g, ' +∞')
          : item
      })
      let option = {
        title: [
          {
            text: this.grpFlter.mainGrp.groupName,
            textStyle: {
              fontSize: 16,
              fontWeight: 700
            }
          },
          {
            text: this.axisTips,
            top: 1,
            left: this.grpFlter.mainGrp.groupName.length * 15 + 20,
            textStyle: {
              fontSize: 13,
              fontWeight: 700,
              color: '#999'
            }
          }
        ],
        tooltip: {
          trigger: 'item',
          confine: true,
          formatter: function(params) {
            return (
              xAxis[params.data[0]] +
              ' X ' +
              yAxis[params.data[1]] +
              '<br/>数值：' +
              params.data[2] +
              '<br/>占比：' +
              ((params.data[2] / _this.grpTotal) * 100).toFixed(2) +
              '%'
            )
          }
        },
        grid: {
          top: '40',
          left: 0,
          right: '80',
          bottom: 0,
          containLabel: true
        },
        xAxis: {
          type: 'category',
          data: xAxis,
          splitArea: {
            show: true
          }
        },
        yAxis: {
          type: 'category',
          data: yAxis,
          splitArea: {
            show: true
          }
        },
        visualMap: {
          min: Math.min(...values),
          max: Math.max(...values),
          calculable: true,
          top: '40',
          right: 0
        },
        series: [
          {
            type: 'heatmap',
            data: series,
            selectedMode: 'multiple',
            label: {
              show: true,
              formatter: function(params) {
                const value = params.data[2]
                const percent = ((value / _this.grpTotal) * 100).toFixed(2) + '%'
                return `${value} （${percent}）`
              }
            },
            emphasis: {
              itemStyle: {
                shadowBlur: 10,
                shadowColor: 'rgba(0,0,0,0.5)'
              }
            }
          }
        ]
      }
      this.chart.setOption(option, true)
      this.chart.on('click', params => {
        this.initDrill(params)
      })
      window.addEventListener('resize', () => {
        this.chart.resize()
      })
    },
    initDrill(params) {
      let index = this.drillGrps.findIndex(
        item => item.mainDrill.seriesId === params.dataIndex + '-' + params.seriesIndex
      )
      if (index >= 0) {
        this.drillGrps.splice(index, 1)
        return
      }
      let drillGrp = {
        mainDrill: {
          seriesId: params.dataIndex + '-' + params.seriesIndex,
          tagNm: this.grpFlter.mainGrp.tagNm,
          name: params.name,
          labTbl: this.grpFlter.mainGrp.labTbl,
          oprator: '=',
          datTyp: this.$dictDb('value_type')[this.grpFlter.mainGrp.valueType],
          logicTyp: 'and',
          labFldMap: this.grpFlter.mainGrp.labFldMap,
          dtTyp: '',
          labId: this.grpFlter.mainGrp.labId,
          isDerLabel: '0',
          val: '',
          valLft: '',
          valRit: '',
          valArray: []
        }
      }
      // 因热力图没有传出xy轴数据，从options里面拿
      const options = this.chart.getOption()
      let seriesName = params.seriesName
      let xIndex = params.seriesIndex
      let yIndex = params.dataIndex
      if (this.profile.graphType === 'heat') {
        const xName = options.xAxis[0].data[params.value[0]]
        const yName = options.yAxis[0].data[params.value[1]]
        seriesName = options.yAxis[0].data[params.value[1]]
        if (this.grpFlter.mainGrp.groupTyp !== 'enum') {
          xIndex = this.grpFlter.mainGrp.labGrps.findIndex(item => item.valLft + ' ~ ' + item.valRit == xName)
        }
        if (this.grpFlter.subGrp.groupTyp !== 'enum') {
          yIndex = this.grpFlter.subGrp.labGrps.findIndex(item => item.valLft + ' ~ ' + item.valRit == yName)
        }
      }
      if (this.grpFlter.mainGrp.groupTyp === 'enum') {
        const target = this.grpFlter.mainGrp.enums.find(item => item.cdDesc === params.name)
        drillGrp.mainDrill.val = target ? target.cdVal : params.name === '是' ? 1 : 0
      } else {
        drillGrp.mainDrill.oprator = 'a<=x<b'
        drillGrp.mainDrill.valLft = this.grpFlter.mainGrp.labGrps[xIndex].valLft
        drillGrp.mainDrill.valRit = this.grpFlter.mainGrp.labGrps[xIndex].valRit
      }
      if (this.grpFlter.subGrp && this.grpFlter.subGrp.labId) {
        drillGrp.subDrill = {
          seriesId: params.dataIndex + '-' + params.seriesIndex,
          tagNm: this.grpFlter.subGrp.tagNm,
          name: seriesName,
          labTbl: this.grpFlter.subGrp.labTbl,
          oprator: '=',
          datTyp: this.$dictDb('value_type')[this.grpFlter.subGrp.valueType],
          logicTyp: 'and',
          labFldMap: this.grpFlter.subGrp.labFldMap,
          dtTyp: '',
          labId: this.grpFlter.subGrp.labId,
          isDerLabel: '0',
          val: '',
          valLft: '',
          valRit: '',
          valArray: []
        }
        if (this.grpFlter.subGrp.groupTyp === 'enum') {
          const target = this.grpFlter.subGrp.enums.find(item => item.cdDesc === params.seriesName)
          drillGrp.subDrill.val = target ? target.cdVal : params.seriesName === '是' ? 1 : 0
        } else {
          drillGrp.subDrill.oprator = 'a<=x<b'
          drillGrp.subDrill.valLft = this.grpFlter.subGrp.labGrps[yIndex].valLft
          drillGrp.subDrill.valRit = this.grpFlter.subGrp.labGrps[yIndex].valRit
        }
      }
      this.drillGrps.push(drillGrp)
    },
    submit() {
      if (!this.drillGrps.length) {
        this.$message.info('请选择深入分析的维度！')
        return
      }
      this.$emit('updateDrill', this.drillGrps)
      this.beforeClose()
    },
    beforeClose() {
      this.profile = {}
      this.grpFlter = {}
      this.grpTotal = 0
      this.drillGrps = []
      if (this.chart) {
        this.chart.dispose()
        this.chart = null
      }
      this.dialogVisible = false
    }
  }
}
</script>

<style lang="scss">
.tag-deep-dialog {
  .title-tips {
    font-size: 14px;
    margin-left: 10px;
    color: orange;
  }
  #deep-box {
    float: left;
    height: 300px;
    width: calc(100% - 350px);
  }
  .show-box {
    float: right;
    width: 330px;
    height: 300px;
    border: 1px solid $border-color;
    .box-title {
      font-size: 17px;
      margin: 10px;
      padding-left: 10px;
      color: $theme-color;
      position: relative;
      &:before {
        width: 3px;
        content: '';
        background-color: $theme-color;
        position: absolute;
        top: 0;
        bottom: 0;
        left: 0;
      }
    }
    .show-content {
      height: calc(100% - 20px);
      overflow-y: auto;
      li {
        font-size: 16px;
        padding: 10px 25px;
        line-height: 25px;
        color: $theme-color;
        position: relative;
        &:before {
          width: 10px;
          height: 10px;
          content: '';
          background-color: $theme-color;
          border-radius: 50%;
          position: absolute;
          top: 17px;
          left: 5px;
        }
      }
    }
    .no-record {
      font-size: 17px;
      text-align: center;
    }
  }
}
</style>
